<script context="module">
	export function preload({ query }) {
		return {
			version: query.version || 'latest',
			gist_id: query.gist,
			example: query.example || 'hello-world'
		};
	} 
</script>

<script>

	import { onMount } from 'svelte';
	import { process_example } from './_utils/process_example.js';
	import AppControls from './_components/AppControls/index.svelte';

	import Repl from '../../components/Repl/index.svelte';

	export let version, example, gist_id;

	console.log({ example });

	let repl;
	let gist;
	let name = 'loading...';
	let zen_mode = false;
	let sync_in_progress = false;

	$: if (typeof history !== 'undefined') {
		const params = [];

		if (version !== 'latest') params.push(`version=${version}`);
		if (gist_id) params.push(`gist=${gist_id}`);
		else if (example) params.push(`example=${example}`);

		const url = params.length > 0
			? `repl?${params.join('&')}`
			: 'repl';

		history.replaceState({}, 'x', url);
	}

	function handle_sync_state_change(e) {
		sync_in_progress = e.detail.state;
	}

	onMount(() => {
		if (version !== 'local') {
			let svelteversion = Promise.resolve(version);
			if (version == "latest") {
				// get the latest supported svelte version
				svelteversion = fetch('https://unpkg.com/svelte-native@latest/package.json')
								.then(r => r.json())
								.then(pkg => {
									return pkg.peerDependencies.svelte;
								});
			}

			svelteversion
					.then(version => fetch(`https://unpkg.com/svelte@${version || 'beta'}/package.json`))
					.then(r => r.json())
					.then(pkg => {
						version = pkg.version;
					});
		}

		if (gist_id) {
			fetch(`gist/${gist_id}`).then(r => r.json()).then(data => {
				gist = data;
				const { id, description, files } = data;

				name = description;

				const components = Object.keys(files)
					.map(file => {
						const dot = file.lastIndexOf('.');
						if (!~dot) return;

						const source = files[file].content;

						let type = file.slice(dot + 1);
						if (type === 'html') type = 'svelte';

						return {
							name: file.slice(0, dot),
							type,
							source
						};
					})
					.filter(x => x.type === 'svelte' || x.type === 'js')
					.sort((a, b) => {
						if (a.name === 'App' && a.type === 'svelte') return -1;
						if (b.name === 'App' && b.type === 'svelte') return 1;

						if (a.type !== b.type) return a.type === 'svelte' ? -1 : 1;

						return a.name < b.name ? -1 : 1;
					});

				repl.set({ components });
			});
		}
	});

	function load_example(slug) {
		console.log(`loading ${slug}`);

		fetch(`examples/${slug}.json`).then(async response => {
			if (response.ok) {
				const data = await response.json();

				name = data.title;

				const components = process_example(data.files);
				repl.set({ components });

				gist = null;
			}
		}).catch(() => "failed to load example");
	}

	function handle_fork(event) {
		example = null;
		gist = event.detail.gist;
		gist_id = gist.id;
	}

	$: if (process.browser && example) {
		load_example(example);
	}

</script>

<style>
	.repl-outer {
		position: relative;
		height: calc(100vh - var(--nav-h));
		--app-controls-h: 5.6rem;
		--pane-controls-h: 4.2rem;
		overflow: hidden;
		background-color: var(--back);
		padding: var(--app-controls-h) 0 0 0;
		box-sizing: border-box;
	}

	.zen-mode {
		position: fixed;
		width: 100%;
		height: 100%;
		top: 0;
		z-index: 11;
	}

	.pane {
		width: 100%;
		height: 100%
	}

	.loading {
		text-align: center;
		color: var(--second);
		font-weight: 400;
		margin: 2em 0 0 0;
		opacity: 0;
		animation: fade-in .4s;
		animation-delay: .2s;
		animation-fill-mode: both;
	}

	@keyframes fade-in {
		0% {
			opacity: 0
		}

		100% {
			opacity: 1
		}
	}

	.input {
		padding: 2.4em 0 0 0;
	}
</style>


<svelte:head>
	<title>{name} • REPL • Svelte Native</title>
</svelte:head>

<div class="repl-outer {zen_mode ? 'zen-mode' : ''}">
	<AppControls {name} {gist} {repl} {sync_in_progress} bind:zen_mode on:forked={handle_fork} />

	{#if process.browser}
		<Repl bind:this={repl} {version} on:syncstatechange={handle_sync_state_change} />
	{/if}
</div>